#!/usr/bin/perl


$data = <STDIN>;
while ($data =~ /^\s*class\s+(\S+)\s+extends\s+(\S+)(\s+(\S.*\S|\S))?/gm)
{
	my $class_name = $1;
	my $base_class = $2;
	my $desc = $4;
	my %vars;
	my %desc;
	my @vars;
	my $is_list_imp = 0;
	
	print "class $class_name\n";
	$data = <STDIN>;
	while ($data =~ /^\s+(\S+)\s+(\S+)(\s+(\S.*\S|\S))?/mg)
	{
		my $type = $1;
		my $name = $2;
		$type =~ s/_/ /g;
		$vars{$name} = $type;
		$desc{$name} = $4 || "";
		$is_list_imp = 1 if ($type =~ /List</);
		push @vars, $name;
		print "\t$name: $type\n";
		$data = <STDIN>;
	}

	# write
	open OUT, "> $class_name.java";
	print OUT "package IC.AST.nodes;\n\n";
	print OUT "import java.util.List;\n"  if ($is_list_imp);
	print OUT "import IC.AST.*;\n\n";

	my $is_abstract = ! @vars && ! ( $class_name =~ /NullLiteral|Break|Continue|ThisExpr/ );

	print OUT "/**\n * $desc\n */\npublic ";
	print OUT "abstract " if ($is_abstract);
	print OUT "class $class_name extends $base_class {\n";

	for (@vars) {
		my ($name,$type,$desc) = ($_,$vars{$_},$desc{$_});
		print OUT "\tprivate $type $name;";
		print OUT "\t// $desc" if ($desc);
		print OUT "\n"; 
	}

	# constructor
	print OUT "\n";
	print OUT "\t/**\n".(join "", ( map { "\t * \@param $_ ".$desc{$_}."\n" } @vars )),
				"\t * \@param line the node line number\n",
				"\t * \@param column the node column number\n", 
				"\t */\n";
	print OUT "\tpublic $class_name(".  
				(join ", ", ( map { $vars{$_}." ".$_ } @vars));
	print OUT ", " if (@vars);
	print OUT "int line, int column) {\n";
	print OUT "\t\tsuper(line,column);\n";
	print OUT map { "\t\tthis.$_ = $_;\n" } @vars;
	print OUT "\t}\n\n";
	

	# getters
	for (@vars) {
		my ($name,$type,$desc) = ($_,$vars{$_},$desc{$_});

		my $name2 = ($name =~ /^is/)?$name:"get".ucfirst($name);

		print OUT "\t/**\n\t * \@return $desc\n\t */\n";
		print OUT "\tpublic $type $name2() {\n";
		print OUT "\t\treturn this.$name;\n";
		print OUT "\t}\n\n"; 
	}

	# accept
	if (! $is_abstract) {
		print OUT "\tpublic Object accept(Visitor v) {\n";
		print OUT "\t\treturn v.visit(this);\n";
		print OUT "\t}\n";
	}
	$data = <STDIN>;
	print OUT "}\n";
	close OUT;

}
